package com.ruoyi.law.controller;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageCondition;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.law.domain.entity.LawLabel;
import com.ruoyi.law.service.ILawLabelService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 标签管理 前端控制器
 * </p>
 *
 * @author code
 * @since 2022-11-26
 */
@Api(tags = "标签管理")
@RestController
@RequestMapping("/label")
public class LawLabelController extends BaseController {

    @Autowired
    private ILawLabelService labelService;

    @Anonymous
    @ApiOperation("列表")
    @GetMapping("/list")
    public R<Page<LawLabel>> list(PageCondition<LawLabel> pageCondition) {
        Page<LawLabel> page = labelService.page(pageCondition.toPage());
        return R.ok(page);
    }

    @Anonymous
    @ApiOperation("详情")
    @GetMapping("/info")
    public R<LawLabel> info(Long id) {
        LawLabel vip = labelService.getById(id);
        return R.ok(vip);
    }

    @ApiOperation("修改")
    @PostMapping("/update")
    public R<Object> update(@RequestBody LawLabel lawLabel) {
        labelService.updateById(lawLabel);
        return R.ok();
    }

    @ApiOperation("新增")
    @PostMapping("/save")
    public R<Object> save(@RequestBody LawLabel lawLabel) {
        Long pid = lawLabel.getPid();
        if (pid != null) {
            // 检查层级
            List<Tree<String>> trees = getTrees(null);
            int level = getLevel(trees, pid.toString(), 1);
            Assert.isFalse(level >= 3, "最多只能有三级标签");
        }

        labelService.save(lawLabel);
        return R.ok();
    }

    @ApiOperation("删除")
    @PostMapping("/delete")
    public R<Object> delete(@RequestBody Long id) {
        // 检查是否有子节点
        Integer count = labelService.lambdaQuery().eq(LawLabel::getPid, id).count();
        Assert.isFalse(count > 0, "请先删除子节点");

        boolean remove = labelService.removeById(id);
        return remove ? R.ok() : R.fail();
    }

    @Anonymous
    @ApiOperation("标签树")
    @ApiImplicitParam(name = "id", value = "标签id(不传查整个树，传了则只查询该id下的一级子节点)")
    @GetMapping("/tree")
    public R<List<Tree<String>>> tree(String id) {
        List<Tree<String>> list = getTrees(id);
        return R.ok(list);
    }

    /**
     * 获取树
     *
     * @param id id
     * @return {@link List}<{@link Tree}<{@link String}>>
     */
    private List<Tree<String>> getTrees(String id) {
        List<LawLabel> lists = labelService.list();

        // 构建树
        String rootId = "";
        TreeNodeConfig config = new TreeNodeConfig();
        // 设置排序字段名
        config.setWeightKey("sort");
        // 如果传了id，则只查询该id下的一级子节点
        if (StrUtil.isNotBlank(id)) {
            rootId = id;
            config.setDeep(1);
        }
        return TreeUtil.build(lists, rootId, config, (lawLabel, tree) -> {
            tree.setId(lawLabel.getId().toString());
            tree.setName(lawLabel.getName());
            tree.setParentId(lawLabel.getPid() == null ? "" : lawLabel.getPid().toString());
            tree.setWeight(lawLabel.getSort());

            tree.putExtra("type", lawLabel.getType());
        });
    }

    /**
     * 递归获取所有子节点id
     *
     * @param list 列表
     * @return {@link List}<{@link String}>
     */
    private List<String> getAllChildren(List<Tree<String>> list) {
        List<String> ids = new ArrayList<>();
        for (Tree<String> tree : list) {
            ids.add(tree.getId());
            // 获取所有子节点id
            List<Tree<String>> children = tree.getChildren();
            if (CollectionUtil.isNotEmpty(children)) {
                List<String> childrenIds = getAllChildren(children);
                ids.addAll(childrenIds);
            }
        }
        return ids;
    }

    /**
     * 查询树的某个节点是第几层
     *
     * @param trees 树
     * @param id    id
     * @param level 深度
     * @return int
     */
    private int getLevel(List<Tree<String>> trees, String id, int level) {
        for (Tree<String> tree : trees) {
            if (tree.getId().equals(id)) {
                return level;
            }
            List<Tree<String>> children = tree.getChildren();
            if (CollectionUtil.isNotEmpty(children)) {
                int level1 = getLevel(children, id, level + 1);
                if (level1 != 0) {
                    return level1;
                }
            }
        }
        return 0;
    }
}
